using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace Acms.SqlDal
{
    public class UserSecurityDal : UserDal
    {
        public UserSecurityDal() : base() { }

        public new enum Fields
        {
            Password,
            Salt,
            PasswordQuestion,
            PasswordAnswer,
            Authenticated,
            Created,
            Locked,
            LastLogin,
            LastActivity,
            LastChangedPassword,
            LastLocked
        }

        protected override void ReadRecord(Hashtable table, SqlDataReader reader)
        {
            base.ReadRecord(table, reader);

            GetReaderValue<string>(Fields.Password, reader, table);
            GetReaderValue<int>(Fields.Salt, reader, table);
            GetReaderValue<string>(Fields.PasswordQuestion, reader, table);
            GetReaderValue<string>(Fields.PasswordAnswer, reader, table);
            GetReaderValue<bool>(Fields.Authenticated, reader, table);
            GetReaderValue<DateTime>(Fields.Created, reader, table);
            GetReaderValue<bool>(Fields.Locked, reader, table);
            GetReaderValue<DateTime?>(Fields.LastLogin, reader, table);
            GetReaderValue<DateTime?>(Fields.LastActivity, reader, table);
            GetReaderValue<DateTime?>(Fields.LastChangedPassword, reader, table);
            GetReaderValue<DateTime?>(Fields.LastLocked, reader, table);
        }

        public new Hashtable[] GetAll()
        {
            SqlCommand cmd = CreateCommand("GetAll");
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetAllPaged(string sortExpression, int startRecord, int pageSize, ref int totalRecords)
        {
            SqlCommand cmd = CreateCommand("GetAllPaged");
            AddInputParameter(cmd, "Sort", sortExpression, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "StartIndex", startRecord, SqlDbType.Int, 255);
            AddInputParameter(cmd, "PageSize", pageSize, SqlDbType.Int, 255);
            AddOutputParameter(cmd, "TotalRecords", SqlDbType.Int, 255);
            Hashtable[] tables = ExecuteGetCollection(cmd);
            totalRecords = GetOutputValue<int>(cmd, "TotalRecords");
            return tables;
        }

        public Hashtable[] GetAllByEmailAddressPaged(string emailAddress, string sortExpression, int startRecord, int pageSize, ref int totalRecords)
        {
            SqlCommand cmd = CreateCommand("GetAllByEmailAddressPaged");
            AddInputParameter(cmd, "EmailAddress", emailAddress, SqlDbType.VarChar, 1000);
            AddInputParameter(cmd, "Sort", sortExpression, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "StartIndex", startRecord, SqlDbType.Int, 255);
            AddInputParameter(cmd, "PageSize", pageSize, SqlDbType.Int, 255);
            AddOutputParameter(cmd, "TotalRecords", SqlDbType.Int, 255);
            Hashtable[] tables = ExecuteGetCollection(cmd);
            totalRecords = GetOutputValue<int>(cmd, "TotalRecords");
            return tables;
        }

        public Hashtable[] GetAllByUsernamePaged(string username, string sortExpression, int startRecord, int pageSize, ref int totalRecords)
        {
            SqlCommand cmd = CreateCommand("GetAllByUsernamePaged");
            AddInputParameter(cmd, "Username", username, SqlDbType.VarChar, 1000);
            AddInputParameter(cmd, "Sort", sortExpression, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "StartIndex", startRecord, SqlDbType.Int, 255);
            AddInputParameter(cmd, "PageSize", pageSize, SqlDbType.Int, 255);
            AddOutputParameter(cmd, "TotalRecords", SqlDbType.Int, 255);
            Hashtable[] tables = ExecuteGetCollection(cmd);
            totalRecords = GetOutputValue<int>(cmd, "TotalRecords");
            return tables;
        }

        public Hashtable GetById(int id, bool updateActivity)
        {
            SqlCommand cmd = CreateCommand("GetById");
            AddInputParameter(cmd, "Id", id, SqlDbType.VarChar, 50);
            AddInputParameter(cmd, "UpdateActivity", updateActivity, SqlDbType.Bit);
            return ExecuteGetItem(cmd);
        }

        public Hashtable GetByUserName(string userName, bool updateActivity)
        {
            SqlCommand cmd = CreateCommand("GetByUserName");
            AddInputParameter(cmd, "UserName", userName, SqlDbType.VarChar, 50);
            AddInputParameter(cmd, "UpdateActivity", updateActivity, SqlDbType.Bit);
            return ExecuteGetItem(cmd);
        }

        public int CountOnline(int minutes)
        {
            SqlCommand cmd = CreateCommand("CountOnline");
            AddInputParameter(cmd, "Minutes", minutes, SqlDbType.Int);
            return ExecuteScalar<int>(cmd);
        }

        public void Delete(int id, object concurencyId)
        {
            SqlCommand cmd = CreateCommand("Delete");
            AddInputParameter(cmd, "Id", id, SqlDbType.Int);
            AddInputParameter(cmd, "ConcurencyId", concurencyId, SqlDbType.Timestamp);
            ExecuteCommand(cmd);
        }

        public void Update(ref int id, string userName, string password, int salt, string passwordQuestion, string passwordAnswer, string emailAddress, bool authenticated, DateTime created, bool locked, DateTime? lastLogin, DateTime? lastActivity, DateTime? lastChangedPassword, DateTime? lastLocked, ref object concurencyId)
        {
            SqlCommand cmd = CreateCommand("Put");
            AddInputParameter(cmd, "Id", id, SqlDbType.Int);
            AddInputParameter(cmd, "UserName", userName, SqlDbType.VarChar);
            AddInputParameter(cmd, "Password", password, SqlDbType.VarChar);
            AddInputParameter(cmd, "Salt", salt, SqlDbType.Int);
            AddInputParameter(cmd, "PasswordQuestion", passwordQuestion, SqlDbType.VarChar);
            AddInputParameter(cmd, "PasswordAnswer", passwordAnswer, SqlDbType.VarChar);
            AddInputParameter(cmd, "EmailAddress", emailAddress, SqlDbType.VarChar);
            AddInputParameter(cmd, "Authenticated", authenticated, SqlDbType.Bit);
            AddInputParameter(cmd, "Created", created, SqlDbType.DateTime);
            AddInputParameter(cmd, "Locked", locked, SqlDbType.Bit);
            AddInputParameter(cmd, "LastLogin", lastLogin, SqlDbType.DateTime);
            AddInputParameter(cmd, "LastActivity", lastActivity, SqlDbType.DateTime);
            AddInputParameter(cmd, "LastChangedPassword", lastChangedPassword, SqlDbType.DateTime);
            AddInputParameter(cmd, "LastLocked", lastLocked, SqlDbType.DateTime);
            AddInputParameter(cmd, "ConcurenyId", concurencyId, SqlDbType.Timestamp);
            AddOutputParameter(cmd, "IdOut", SqlDbType.Int);
            AddOutputParameter(cmd, "ConcurenyIdOut", SqlDbType.Timestamp);

            ExecuteCommand(cmd);

            id = GetOutputValue<int>(cmd, "IdOut");
            concurencyId = GetOutputValue<byte[]>(cmd, "ConcurenyIdOut");
        }
    }
}
